package org.phalanx.server.game;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;

import org.phalanx.server.PhalanxServer;
import org.phalanx.server.ServerCache.AbstractCacheHandler;
import org.phalanx.server.ServerCache.Cache;
import org.phalanx.server.ServerCache.CacheManager;
import org.phalanx.server.ServerCache.Cacheable;
import org.phalanx.server.ServerCache.QueryObject;
import org.phalanx.server.sql.SQLAction;
import org.phalanx.server.sql.SQLManager;

public class GamePlayersCacheHandler implements AbstractCacheHandler {
	public static final String tableName = "usergame";

	public static final String USER_ID = "userid";
	public static final String GAME_ID = "gameid";

	@Override
	public boolean addElementToDB(Cache c, Object newKey, Cacheable newElement) {
		boolean isSuccess = false;

		SQLManager sqlMan = PhalanxServer.getServerInstance().getSQLManager();
		String[] sqlString;

		GameMembers gMember = (GameMembers)newElement;
		Integer userId = (Integer)newKey;

		try {
			if (gMember != null && userId != null){

				Iterator<Integer> i = gMember.getGameIds().iterator();
				int count = 0;
				int statementSize = gMember.getGameIds().size();
				sqlString = new String[statementSize];

				while (i.hasNext()){
					Integer gameId = i.next();


					SQLAction insertGameMembers = new SQLAction(SQLAction.INSERT, tableName);

					insertGameMembers.addField(USER_ID);
					insertGameMembers.addField(GAME_ID);

					insertGameMembers.addValues(userId.toString());
					insertGameMembers.addValues(gameId.toString());

					sqlString[count++] = insertGameMembers.getActionString();
				}

				for (int x = 0; x < sqlString.length; x++){
					sqlMan.insertQuery(sqlString[x]);
				}

				isSuccess = true;
			}
		} catch (SQLException se){}

		return isSuccess;
	}

	@Override
	public boolean deleteObjectFromDB(Cache c, Object newKey,
			Cacheable newElement) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public ArrayList<Cacheable> getMultipleObjectsFromDB(Cache c,
			Object newKey, boolean cacheUpdate) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Cacheable getObjectFromDB(Cache c, Object newKey, boolean cacheUpdate) {
		SQLManager sqlMan = PhalanxServer.getServerInstance().getSQLManager();
		ArrayList<QueryObject> results = new ArrayList<QueryObject>();
		GameMembers newMember = null;

		QueryObject gameMemberQuery = new QueryObject();
		gameMemberQuery.setInteger(USER_ID, 0);
		gameMemberQuery.setInteger(GAME_ID, 0);

		SQLAction selectMember = new SQLAction(SQLAction.SELECT, tableName);
		selectMember.addField("*");
		selectMember.addSearchCriteriaAND(USER_ID, SQLAction.EQUALS, newKey.toString());


		try {
			results = sqlMan.getQuery(selectMember.getActionString(), gameMemberQuery);

			Iterator<QueryObject> i = results.iterator();

			while (i.hasNext()){
				QueryObject oneResult = i.next();

				Integer gameId = oneResult.getInteger(GAME_ID);

				if (newMember == null){
					Integer userId = oneResult.getInteger(USER_ID);
					newMember = new GameMembers(userId);
				}

				newMember.addGameId(gameId);

			}
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return newMember;
	}

	@Override
	public boolean populateCache(Cache c) {
		boolean isSuccess = false;

		SQLManager sqlMan = PhalanxServer.getServerInstance().getSQLManager();
		ArrayList<QueryObject> results = new ArrayList<QueryObject>();

		QueryObject gamePlayerQuery = new QueryObject();
		gamePlayerQuery.setInteger(USER_ID, 0);
		gamePlayerQuery.setInteger(GAME_ID, 0);

		SQLAction getAllUsers = new SQLAction(SQLAction.SELECT, tableName);
		getAllUsers.addField("*");

		try {
			results = sqlMan.getQuery(getAllUsers.getActionString(), gamePlayerQuery);
			CacheManager cacheMgr = PhalanxServer.getServerInstance().getCacheManager();

			for (int i = 0; i < results.size(); i++){
				QueryObject temp = results.get(i);

				Integer uID = temp.getInteger(USER_ID);
				Integer gID = temp.getInteger(GAME_ID);

				// Check if games and users exist

				Cacheable settings = cacheMgr.getElement("GameListCache", gID);
				Cacheable phalanxUser = cacheMgr.getElement("UserCache", uID);

				if (settings != null && phalanxUser != null){
					GameMembers members = (GameMembers)c.get(uID);

					if (members == null){
						members = new GameMembers(uID);
					}

					members.addGameId(gID);

					c.put(uID, members);
				}
			}
			isSuccess = true;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}


		return isSuccess;
	}

	@Override
	public boolean updateElementToDB(Cache c, Object newKey,
			Cacheable newElement) {
		boolean isSuccess = false;
		ArrayList<Integer> dupeItems = new ArrayList<Integer>();
		SQLManager sqlMan = PhalanxServer.getServerInstance().getSQLManager();

		Integer userId = (Integer)newKey;
		GameMembers alterMember = (GameMembers)newElement;

		Iterator<Integer> i = alterMember.getGameIds().iterator();

		try {
			QueryObject gamePlayerQuery = new QueryObject();
			gamePlayerQuery.setInteger(USER_ID, 0);
			gamePlayerQuery.setInteger(GAME_ID, 0);
			
			SQLAction getOlderData = new SQLAction(SQLAction.SELECT, tableName);
			getOlderData.addField("*");
			getOlderData.addSearchCriteriaAND(USER_ID, SQLAction.EQUALS, userId.toString());
			
			ArrayList<QueryObject> results = sqlMan.getQuery(getOlderData.getActionString(), gamePlayerQuery);
			
			Iterator<QueryObject> oldData = results.iterator();
			
			while (oldData.hasNext()){
				Integer gameIdOld = oldData.next().getInteger(GAME_ID);
				
				if (alterMember.getGameIds().contains(gameIdOld)){
					dupeItems.add(gameIdOld);
				}
			}
			
			while (i.hasNext()){
				Integer gameId = i.next();

				if (!dupeItems.contains(gameId)){
					SQLAction updateGameMember = new SQLAction(SQLAction.INSERT, tableName);

					updateGameMember.addField(USER_ID);
					updateGameMember.addField(GAME_ID);

					updateGameMember.addValues(userId.toString());
					updateGameMember.addValues(gameId.toString());

					sqlMan.insertQuery(updateGameMember.getActionString());
				}
			}
		} catch (SQLException se){
			se.printStackTrace();
		}


		return isSuccess;
	}

}
